package com.ifp.opengate.boot.utils;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.ifp.core.log.Trace;
import com.ifp.core.util.StringUtil;
import com.ifp.opengate.boot.bean.ErrorBean;
import com.ifp.opengate.boot.constants.Constants;
import com.ifp.opengate.boot.emum.ErrorEnum;

/**
 * @author gylio
 */
@Component("uniErrCodeUtils")
public class UniErrCodeUtils {

    @Autowired
    private RedisUtils redisUtils;

    private Map<Object, Object> unifiedErrorCodeMap = new HashMap<>();

    public void setunifiedErrorCodeMapInfo(Object key, Object value) {
        unifiedErrorCodeMap.put(key, value);
    }

    public String removeunifiedErrorCode(Object uecKey) {
        try {
            unifiedErrorCodeMap.remove(uecKey);
            Trace.logError(Trace.MODULE_CORE, "统一错误码缓存{}清除成功", uecKey);
            return ErrorEnum.success.code();
        } catch (Exception e) {
            Trace.logError(Trace.MODULE_CORE, "统一错误码缓存{}清除异常", uecKey);
            return ErrorEnum.error.code();
        }
    }

    public String initOneUniErrCode(String uecKey) {
        try {
            Object message = redisUtils.hmget(Constants.OPEN_GATE + "_" + uecKey);
            setunifiedErrorCodeMapInfo(uecKey, message);
            Trace.logError(Trace.MODULE_CORE, "统一错误码缓存{}添加成功", uecKey);
            return ErrorEnum.success.code();
        } catch (Exception e) {
            Trace.logError(Trace.MODULE_CORE, "统一错误码缓存{}添加异常", uecKey);
            return ErrorEnum.error.code();
        }
    }

    public Map getUniErrCodeInfo(String errorCode, String oldErrorMsg, String apiCodeVer, String sysCode,
        String channel) {
        Map<String, String> hashMap = new HashMap<String, String>();
        ErrorBean errorBean = new ErrorBean(errorCode, oldErrorMsg, -1);
        String emKey = "uniErrCode_" + errorCode;// 三个参数都不存在
        checkError(errorBean, emKey);
        // 检查系统错误是否存在并优先
        checkSingleCode(emKey, sysCode, errorBean);
        // 检查渠道错误是否存在并优先
        checkSingleCode(emKey, channel, errorBean);
        // 检查api错误是否存在并优先
        checkSingleCode(emKey, apiCodeVer, errorBean);
        // 检查系统+渠道错误是否存在并优先
        chechDubbleCode(emKey, sysCode, channel, errorBean);
        // 检查api+系统错误是否存在并优先
        chechDubbleCode(emKey, apiCodeVer, sysCode, errorBean);
        // 检查api+渠道错误是否存在并优先
        chechDubbleCode(emKey, apiCodeVer, channel, errorBean);
        // 检查api+渠道+系统错误是否存在并优先
        checkThreeCode(emKey, apiCodeVer, sysCode, channel, errorBean);
        hashMap.put("errorCode", errorBean.getErrorCode());
        hashMap.put("errorMsg", errorBean.getErrorMsg());
        return hashMap;
    }

    /**
     * 检查三个参数同时存在
     * 
     * @param errorCode
     * @param firstCode
     * @param secondCode
     * @param thirdCode
     * @param errorBean
     */
    private void checkThreeCode(String errorCode, String firstCode, String secondCode, String thirdCode,
        ErrorBean errorBean) {
        String emKey;
        if (StringUtil.hasText(firstCode) && StringUtil.hasText(secondCode) && StringUtil.hasText(thirdCode)) {
            emKey = errorCode + "_" + firstCode + "_" + secondCode + "_" + thirdCode;// 三个存在
            checkError(errorBean, emKey);
        }
    }

    /**
     * 检查两个参数同时存在
     * 
     * @param errorCode
     * @param firstCode
     * @param secondCode
     * @param errorBean
     */
    private void chechDubbleCode(String errorCode, String firstCode, String secondCode, ErrorBean errorBean) {
        String emKey;
        if (StringUtil.hasText(firstCode)) {
            if (StringUtil.hasText(secondCode)) {
                emKey = errorCode + "_" + firstCode + "_" + secondCode;// 有API和关联系统
                checkError(errorBean, emKey);
            } else {
                emKey = errorCode + "_" + firstCode + "_" + Constants.ALL_SYS;// 有API和关联系统
                checkError(errorBean, emKey);
            }

        }
    }

    /**
     * 检查只有一个参数存在
     * 
     * @param errorCode
     * @param firstCode
     * @param errorBean
     */
    private void checkSingleCode(String errorCode, String firstCode, ErrorBean errorBean) {
        String emKey;
        if (StringUtil.hasText(firstCode)) {
            emKey = errorCode + "_" + firstCode;// 只有api存在
            checkError(errorBean, emKey);
        }
    }

    /**
     * 检查没有参数存在
     * 
     * @param errorBean
     * @param emKey
     */
    private void checkError(ErrorBean errorBean, String emKey) {
        ErrorBean errorBeanTemp = getErrorBean(emKey, errorBean.getLevel());
        if (errorBeanTemp != null) {
            errorBean.setErrorCode(errorBeanTemp.getErrorCode());
            errorBean.setErrorMsg(errorBeanTemp.getErrorMsg());
            errorBean.setLevel(errorBeanTemp.getLevel());
        }
    }

    private ErrorBean getErrorBean(String emKey, int level) {
        Map<Object, Object> ecomap = (Map<Object, Object>)unifiedErrorCodeMap.get(emKey);
        if (ecomap == null || ecomap.isEmpty()) {
            return null;
        }
        String emiLevel = (String)ecomap.get("emiLevel");
        // if (level == -1 || Integer.parseInt(emiLevel) < level) {
        ErrorBean errorBean = new ErrorBean();
        errorBean.setLevel(Integer.parseInt(emiLevel));
        errorBean.setErrorCode((String)ecomap.get(Constants.NEW_ERROR_CODE));
        errorBean.setErrorMsg((String)ecomap.get(Constants.NEW_ERROR_MSG));
        return errorBean;
        /* }else {
        	return null;
        } */
    }

}
